/**
 * 手机号脱敏函数
 * @param {string|HTMLElement} el 元素
 * @returns
 * @see https://www.zhangxinxu.com/wordpress/2022/01/js-highlight-dom-node/
 * @example
 * highlight(".p"); // 元素选择器
 * CSS 中设置：{::highlight(tel-highlight) { background-color: currentColor; }}
 *
 */
export function desensitization(el) {
  if (typeof el == "string") {
    el = document.querySelector(el);
  }
  if (!el) return;
  const str = el.textContent;
  const arrIndex = str.match(/1\d{10}/g).map((tel) => str.indexOf(tel));
  const arrRange = arrIndex.map((start) => {
    const range = new Range();
    range.setStart(el.firstChild, start + 3);
    range.setEnd(el.firstChild, start + 7);
    return range;
  });
  const highlight = new Highlight(...arrRange);
  CSS.highlights.set("tel-highlight", highlight);
}

/**
 * 导出一个函数，用于在文章中高亮显示搜索结果
 * @param {HTMLInputElement} query
 * @param {string|HTMLElement} article
 * @returns
 * @see https://www.zhangxinxu.com/wordpress/2022/01/js-highlight-dom-node/
 * @exports
 *  在CSS 中设置：{::highlight(search-highlight) { background-color: yellow; }}
 *
 */
export function searchHighlight(query, article) {
  // 如果article是字符串类型，则将其转换为DOM元素
  if (typeof article == "string") {
    article = document.querySelector(el);
  }
  // 如果article不存在，则返回
  if (!article) return;
  // 创建一个TreeWalker对象，用于遍历article中的所有文本节点
  const treeWalker = document.createTreeWalker(article, NodeFilter.SHOW_TEXT);
  // 创建一个数组，用于存储所有的文本节点
  const allTextNodes = [];
  // 获取第一个文本节点
  let currentNode = treeWalker.nextNode();
  // 遍历所有的文本节点，并将其添加到allTextNodes数组中
  while (currentNode) {
    allTextNodes.push(currentNode);
    currentNode = treeWalker.nextNode();
  }
  // 监听query的input事件
  query.addEventListener("input", () => {
    // 如果CSS.highlight不存在，则返回
    if (!CSS.highlight) {
      article.textContent = "CSS Custom Highlight API not supported.";
      return;
    }
    // 清除之前的搜索结果高亮
    CSS.highlights.clear();
    // 获取query的值，并将其转换为小写
    const str = query.value.trim().toLowerCase();
    // 如果query的值为空，则返回
    if (!str) return;
    // 遍历所有的文本节点，找到匹配的字符串，并将其高亮显示
    const regs = allTextNodes.map((el) => {
      return { el, text: el.textContent.toLowerCase() }.map(({ text, e }) => {
        const indices = [];
        let startPos = 0;
        while (startPos < text.length) {
          const index = text.indexOf(str, startPos); // 找到匹配的字符串
          if (index === -1) break;
          indices.push(index);
          startPos = index + str.length;
        }
        return indices.map((index) => {
          const rge = new Range();
          rge.setStart(e.firstChild, index);
          rge.setEnd(e, index + str.length);
          return rge;
        });
      });
    });
    // 创建一个Highlight对象，用于高亮显示搜索结果
    const searchResultsHighlight = new Highlight(...regs.flat());
    // 将搜索结果高亮添加到CSS.highlights中
    CSS.highlights.set("search-highlight", searchResultsHighlight);
  });
}
